<!--  -->
<template>
  <param-control
    paramTitle="Trajectory Compression Algorithm"
    defaultSelectedAlgorithm="ATIPE"
    :radioObjects="radioObjects"
    v-loading="loading"
    element-loading-text="is processing..."
    @selectRadio="getSelectedAlgorithm"
  >
    <data-dialog
      v-model="dialogTableVisible"
      title="Select Data to Compress"
      filter-name-suffix="_compress"
      @confirmDialog="execute"
    ></data-dialog>
    <el-col :span="24">
      <el-form
        class="algorithm-param-form"
        ref="formRef"
        :model="formData"
        :rules="validateRules"
        label-position="top"
      >
        <!-- ATIPE -->
        <el-form-item v-if="selectedAlgorithm == 'ATIPE'"
          ><span>No parameters need!</span></el-form-item
        >
        <!-- DP -->
        <el-form-item v-if="selectedAlgorithm == 'DP'" label="dis_threshold" prop="DP_disThreshold">
          <el-input
            v-model.number="formData.DP_disThreshold"
            clearable
            size="small"
            placeholder="Input threshold"
          ></el-input>
        </el-form-item>
        <!-- AC -->
        <el-row v-if="selectedAlgorithm == 'AC'">
          <el-col :span="12">
            <el-form-item label="angle_threshold" prop="AC_angleThreshold"
              ><el-slider
                v-model="formData.AC_angleThreshold"
                :max="90"
                :format-tooltip="
                  (value) => {
                    return value + '°';
                  }
                "
              ></el-slider></el-form-item
          ></el-col>
          <el-col :span="12">
            <el-form-item label="acc_angle_threshold" prop="AC_accAngleThreshold">
              <el-slider
                v-model="formData.AC_accAngleThreshold"
                :max="90"
                :format-tooltip="
                  (value) => {
                    return value + '°';
                  }
                "
              >
              </el-slider></el-form-item
          ></el-col>
        </el-row> </el-form
    ></el-col>
    <el-col :span="18"></el-col>
    <el-col :span="6">
      <el-button class="common-text" type="primary" @click="showDialog">EXECUTE</el-button>
    </el-col>
  </param-control>
  <process-statics
    :loading="loading"
    :process-time="processTime"
    @cancelProcess="
      this.loading = false;
      this.abortController.abort();
    "
  ></process-statics>
</template>

<script>
// 这里可以导入其他文件（比如：组件，工具js，第三方插件js，json文件，图片文件等等）
// 例如：import 《组件名称》 from '《组件路径》';
import { ElMessage } from 'element-plus';
import { AlgorithmObject } from '@/util/type/AlgorithmObject.js';
import { ValidateRulesUtil } from '@/util/type/ValidateRulesUtil.js';
import { TraObject } from '@/util/type/TraObject';
import ParamControl from '@/components/ParamControl.vue';
import ProcessStatics from '@/components/ProcessStatics.vue';
import DataDialog from '@/components/DataDialog.vue';
import axios from 'axios';
export default {
  data() {
    // 这里存放数据
    return {
      loading: false,
      processTime: 0, //算法执行时间
      abortController: null, //用于中断算法执行
      algorithmObject: null, //构建的算法对象
      dialogTableVisible: false, //是否显示弹窗
      formRef: null, //对form表单的引用
      // 表单验证规则
      validateRules: {
        DP_disThreshold: [
          { required: true, message: 'cannot be empty', trigger: 'blur' },
          { type: 'number', message: 'must be a number', trigger: 'blur' },
        ],
        AC_angleThreshold: [
          {
            required: true,
            validator: ValidateRulesUtil.notZero,
            message: 'cannot be 0',
            trigger: 'change',
          },
        ],
        AC_accAngleThreshold: [
          {
            required: true,
            validator: ValidateRulesUtil.notZero,
            message: 'cannot be 0',
            trigger: 'change',
          },
        ],
      },
      //表单数据
      formData: {
        AC_angleThreshold: 30,
        AC_accAngleThreshold: 15,
      },
      // 按钮组对象
      radioObjects: [
        {
          span: 8,
          name: 'ATIPE',
        },
        {
          span: 8,
          name: 'DP',
        },
        {
          span: 8,
          name: 'AC',
        },
      ],
      selectedAlgorithm: null, //选择的压缩算法
    };
  },
  // 监听属性 类似于data概念
  computed: {},
  // 监控data中的数据变化
  watch: {},
  // 方法集合
  methods: {
    //获得选择的算法名
    getSelectedAlgorithm(algorithmName) {
      this.selectedAlgorithm = algorithmName;
    },
    //校验并显示弹窗
    async showDialog() {
      try {
        await this.$refs.formRef.validate(); //校验表单
        const algorithmName = this.selectedAlgorithm; //算法名称获取
        const algorithmObject = new AlgorithmObject(algorithmName); //构建算法对象
        //从formData中找到以算法名开头的key
        for (let key in this.formData) {
          if (key.startsWith(algorithmName)) {
            algorithmObject.pushParam(key, this.formData[key]); //添加参数
          }
        }
        if (algorithmName != 'ATIPE') {
          ElMessage({
            message: 'This function not implemented.',
            type: 'warning',
          });
          return;
        }
        this.dialogTableVisible = true; //显示弹窗
        this.algorithmObject = algorithmObject; //传递算法对象
      } catch (err) {
        if (err instanceof TypeError) {
          ElMessage.error(err.message);
        } else {
          // 校验失败
          for (let key in err) {
            const errMessage = err[key][0]['message'];
            ElMessage.error(key + ' ' + errMessage);
          }
        }
      }
    },
    //算法开始执行
    async execute(selectedData) {
      this.dialogTableVisible = false;
      this.loading = true;
      this.abortController = new AbortController();
      const signal = this.abortController.signal;
      let startTime = new Date(); //开始时间
      //定时器，显示执行的时间
      let interval = setInterval(() => {
        if (!this.loading) {
          clearInterval(interval);
        } else {
          this.processTime = (new Date().getTime() - startTime.getTime()) / 1000;
        }
      }, 1000);
      //开始将数据请求到后端进行处理，并得到结果
      try {
        const response = await axios.post(
          '/api/compress',
          {
            trajectories: selectedData['coordsList'],
            algorithmObject: this.algorithmObject,
          },
          { signal },
        );
        this.loading = false; //取消加载动画
        //判断是否结果正常
        if (response['data']['code'] === 200) {
          this.$store.commit(
            'updateTraObjects',
            new TraObject(
              `${selectedData['fileName']}_compress`,
              response['data']['data']['compressed_trajectories'],
            ),
          ); //坐标序列提交到vuex中
          ElMessage.success(response['data']['message']);
        } else {
          ElMessage.error(response['data']['message']);
        }
      } catch (err) {
        if (axios.isCancel(err)) ElMessage.info('execution canceled!');
        else {
          this.loading = false;
          ElMessage.error(err);
        }
      }
    },
  },
  components: {
    ParamControl,
    DataDialog,
    ProcessStatics,
  },
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  // 生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {},
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {}, // 如果页面有keep-alive缓存功能，这个函数会触发
};
</script>
<style lang="scss" scoped>
// el样式定制
.el-button {
  padding: 5px;
  float: right;
}
.el-col {
  margin: 2px 0;
}
</style>
